---
title: "Swift 語法對比"
description: "透過對比 JavaScript 掌握 Swift 語法，涵蓋變數、函數、控制結構和表達式。"
---

## 1. 介紹

### 為什麼語法對比很重要

作為從 JavaScript 轉向 Swift 的開發者，理解語法差異對於編寫清晰、高效的程式碼至關重要。Swift 的語法設計注重安全性、清晰性和表達性，特別強調類型安全和現代程式設計實踐。

**主要學習目標：**
- 理解 Swift 的類型系統和變數宣告
- 掌握函數語法和參數處理
- 學習 Swift 的控制結構和表達式
- 對比 JavaScript 和 Swift 的編碼模式
- 培養 Swift 編碼最佳實踐

## 2. 變數宣告和類型

### 2.1 變數宣告對比

Swift 使用顯式類型註解和類型推斷，比 JavaScript 的動態類型提供更好的安全性。

<UniversalEditor title="變數宣告對比" compare={true}>
```javascript !! js
// JavaScript 變數宣告
let name = "John";           // 字串
const age = 25;              // 數字
var isStudent = true;        // 布林值
let scores = [85, 90, 78];   // 陣列
let person = {               // 物件
    name: "John",
    age: 25
};

// 執行時類型檢查
console.log(typeof name);    // "string"
console.log(typeof age);     // "number"
console.log(typeof isStudent); // "boolean"
```

```swift !! swift
// Swift 變數宣告
let name: String = "John"    // 顯式類型註解
let age = 25                 // 類型推斷 (Int)
let isStudent = true         // 類型推斷 (Bool)
let scores = [85, 90, 78]    // 類型推斷 ([Int])
let person = [               // 字典字面量
    "name": "John",
    "age": 25
]

// 編譯時類型檢查
print(type(of: name))        // String
print(type(of: age))         // Int
print(type(of: isStudent))   // Bool
```
</UniversalEditor>

### 2.2 常數 vs 變數

Swift 明確區分常數（`let`）和變數（`var`），類似於 JavaScript 的 `const` 和 `let`。

<UniversalEditor title="常數 vs 變數" compare={true}>
```javascript !! js
// JavaScript 常數和變數
const PI = 3.14159;          // 常數 - 不能重新賦值
let radius = 5;              // 變數 - 可以重新賦值
var diameter = 10;           // 變數（函數作用域）

// 嘗試重新賦值常數（會導致錯誤）
// PI = 3.14; // TypeError: Assignment to constant variable

radius = 7;                  // 有效的重新賦值
console.log(`面積: ${PI * radius * radius}`);
```

```swift !! swift
// Swift 常數和變數
let pi = 3.14159             // 常數 - 不能重新賦值
var radius = 5               // 變數 - 可以重新賦值

// 嘗試重新賦值常數（會導致編譯錯誤）
// pi = 3.14 // Error: Cannot assign to value: 'pi' is a 'let' constant

radius = 7                   // 有效的重新賦值
print("面積: \(pi * Double(radius) * Double(radius))")
```
</UniversalEditor>

### 2.3 類型註解

Swift 允許顯式類型註解，提高程式碼清晰度和編譯器優化。

<UniversalEditor title="類型註解" compare={true}>
```javascript !! js
// JavaScript - 動態類型
let message = "Hello";       // 字串
let count = 42;              // 數字
let isActive = true;         // 布林值

// 類型可以在執行時改變
message = 123;               // 現在是數字
count = "forty-two";         // 現在是字串
isActive = 1;                // 現在是數字（真值）

console.log(typeof message); // "number"
console.log(typeof count);   // "string"
console.log(typeof isActive); // "number"
```

```swift !! swift
// Swift - 靜態類型和類型註解
let message: String = "Hello"    // 顯式字串類型
let count: Int = 42              // 顯式整數類型
let isActive: Bool = true        // 顯式布林類型

// 類型不能改變 - 這些會導致編譯錯誤：
// message = 123        // Error: Cannot assign value of type 'Int' to type 'String'
// count = "forty-two"  // Error: Cannot assign value of type 'String' to type 'Int'
// isActive = 1         // Error: Cannot assign value of type 'Int' to type 'Bool'

print(type(of: message))     // String
print(type(of: count))       // Int
print(type(of: isActive))    // Bool
```
</UniversalEditor>

## 3. 函數和方法

### 3.1 函數宣告對比

Swift 函數具有更明確的語法，包括參數標籤和返回類型。

<UniversalEditor title="函數宣告對比" compare={true}>
```javascript !! js
// JavaScript 函數宣告
function greet(name) {
    return `Hello, ${name}!`;
}

// 箭頭函數
const greetArrow = (name) => {
    return `Hello, ${name}!`;
};

// 多參數函數
function calculateArea(width, height) {
    return width * height;
}

// 預設參數函數
function greetWithDefault(name = "World") {
    return `Hello, ${name}!`;
}

console.log(greet("Alice"));           // "Hello, Alice!"
console.log(calculateArea(10, 5));     // 50
console.log(greetWithDefault());       // "Hello, World!"
```

```swift !! swift
// Swift 函數宣告
func greet(name: String) -> String {
    return "Hello, \(name)!"
}

// 多參數函數
func calculateArea(width: Double, height: Double) -> Double {
    return width * height
}

// 預設參數函數
func greetWithDefault(name: String = "World") -> String {
    return "Hello, \(name)!"
}

// 外部參數名函數
func greet(person name: String) -> String {
    return "Hello, \(name)!"
}

print(greet(name: "Alice"))            // "Hello, Alice!"
print(calculateArea(width: 10, height: 5)) // 50.0
print(greetWithDefault())              // "Hello, World!"
print(greet(person: "Bob"))            // "Hello, Bob!"
```
</UniversalEditor>

### 3.2 函數類型和閉包

Swift 將函數視為一等公民，具有顯式的函數類型。

<UniversalEditor title="函數類型和閉包" compare={true}>
```javascript !! js
// JavaScript 函數類型和閉包
const add = (a, b) => a + b;
const multiply = (a, b) => a * b;

// 函數作為變數
const operation = add;
console.log(operation(5, 3)); // 8

// 返回函數的函數
const createCalculator = (operation) => {
    return (a, b) => operation(a, b);
};

const calculator = createCalculator(add);
console.log(calculator(10, 5)); // 15

// 高階函數
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(x => x * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
```

```swift !! swift
// Swift 函數類型和閉包
let add: (Int, Int) -> Int = { a, b in a + b }
let multiply: (Int, Int) -> Int = { a, b in a * b }

// 函數作為變數
let operation = add
print(operation(5, 3)) // 8

// 返回函數的函數
func createCalculator(operation: @escaping (Int, Int) -> Int) -> (Int, Int) -> Int {
    return operation
}

let calculator = createCalculator(operation: add)
print(calculator(10, 5)) // 15

// 高階函數
let numbers = [1, 2, 3, 4, 5]
let doubled = numbers.map { $0 * 2 }
print(doubled) // [2, 4, 6, 8, 10]
```
</UniversalEditor>

## 4. 控制結構

### 4.1 條件語句

Swift 的 `if` 語句與 JavaScript 類似，但具有更強的類型檢查。

<UniversalEditor title="條件語句" compare={true}>
```javascript !! js
// JavaScript 條件語句
let age = 18;
let hasLicense = true;

if (age >= 18) {
    console.log("你是成年人");
} else if (age >= 13) {
    console.log("你是青少年");
} else {
    console.log("你是兒童");
}

// 真值/假值
let name = "";
let count = 0;
let isActive = false;

if (name) {
    console.log("提供了姓名");
} else {
    console.log("姓名為空");
}

if (count) {
    console.log("計數非零");
} else {
    console.log("計數為零");
}

// 三元運算子
let status = age >= 18 ? "成年人" : "未成年人";
console.log(status);
```

```swift !! swift
// Swift 條件語句
let age = 18
let hasLicense = true

if age >= 18 {
    print("你是成年人")
} else if age >= 13 {
    print("你是青少年")
} else {
    print("你是兒童")
}

// Swift 需要顯式的布林表達式
let name = ""
let count = 0
let isActive = false

if !name.isEmpty {
    print("提供了姓名")
} else {
    print("姓名為空")
}

if count > 0 {
    print("計數非零")
} else {
    print("計數為零")
}

// 三元運算子
let status = age >= 18 ? "成年人" : "未成年人"
print(status)
```
</UniversalEditor>

### 4.2 Switch 語句

Swift 的 `switch` 語句比 JavaScript 更強大，支援模式匹配。

<UniversalEditor title="Switch 語句" compare={true}>
```javascript !! js
// JavaScript switch 語句
let day = "Monday";

switch (day) {
    case "Monday":
        console.log("工作週開始");
        break;
    case "Tuesday":
    case "Wednesday":
    case "Thursday":
        console.log("週中");
        break;
    case "Friday":
        console.log("TGIF!");
        break;
    case "Saturday":
    case "Sunday":
        console.log("週末!");
        break;
    default:
        console.log("無效的日期");
}

// 帶 fall-through 的 switch（需要顯式 break）
let grade = "B";
switch (grade) {
    case "A":
        console.log("優秀");
        break;
    case "B":
        console.log("良好");
        break;
    case "C":
        console.log("一般");
        break;
    default:
        console.log("需要改進");
}
```

```swift !! swift
// Swift switch 語句和模式匹配
let day = "Monday"

switch day {
case "Monday":
    print("工作週開始")
case "Tuesday", "Wednesday", "Thursday":
    print("週中")
case "Friday":
    print("TGIF!")
case "Saturday", "Sunday":
    print("週末!")
default:
    print("無效的日期")
}

// Swift switch 和範圍匹配
let score = 85
switch score {
case 90...100:
    print("A")
case 80..<90:
    print("B")
case 70..<80:
    print("C")
case 60..<70:
    print("D")
case 0..<60:
    print("F")
default:
    print("無效分數")
}

// Swift switch 和元組匹配
let point = (2, 0)
switch point {
case (0, 0):
    print("原點")
case (_, 0):
    print("在 x 軸上")
case (0, _):
    print("在 y 軸上")
case (-2...2, -2...2):
    print("接近原點")
default:
    print("其他地方")
}
```
</UniversalEditor>

### 4.3 迴圈

Swift 提供多種迴圈結構，適用於不同場景。

<UniversalEditor title="迴圈對比" compare={true}>
```javascript !! js
// JavaScript 迴圈
const numbers = [1, 2, 3, 4, 5];

// For 迴圈
for (let i = 0; i < numbers.length; i++) {
    console.log(numbers[i]);
}

// For...of 迴圈（遍歷值）
for (const num of numbers) {
    console.log(num);
}

// For...in 迴圈（遍歷鍵）
const person = { name: "John", age: 30 };
for (const key in person) {
    console.log(`${key}: ${person[key]}`);
}

// While 迴圈
let count = 0;
while (count < 5) {
    console.log(count);
    count++;
}

// Do...while 迴圈
let i = 0;
do {
    console.log(i);
    i++;
} while (i < 3);

// 陣列方法
numbers.forEach(num => console.log(num));
const doubled = numbers.map(num => num * 2);
const evens = numbers.filter(num => num % 2 === 0);
```

```swift !! swift
// Swift 迴圈
let numbers = [1, 2, 3, 4, 5]

// For-in 迴圈（遍歷值）
for num in numbers {
    print(num)
}

// For-in 迴圈和範圍
for i in 0..<numbers.count {
    print(numbers[i])
}

// For-in 迴圈和 stride
for i in stride(from: 0, to: 10, by: 2) {
    print(i) // 0, 2, 4, 6, 8
}

// While 迴圈
var count = 0
while count < 5 {
    print(count)
    count += 1
}

// Repeat-while 迴圈（相當於 do-while）
var i = 0
repeat {
    print(i)
    i += 1
} while i < 3

// 字典迭代
let person = ["name": "John", "age": "30"]
for (key, value) in person {
    print("\(key): \(value)")
}

// 陣列方法
numbers.forEach { print($0) }
let doubled = numbers.map { $0 * 2 }
let evens = numbers.filter { $0 % 2 == 0 }
```
</UniversalEditor>

## 5. 運算子和表達式

### 5.1 基本運算子

Swift 運算子與 JavaScript 類似，但具有更強的類型安全性。

<UniversalEditor title="基本運算子" compare={true}>
```javascript !! js
// JavaScript 運算子
let a = 10;
let b = 3;

// 算術運算子
console.log(a + b);  // 13
console.log(a - b);  // 7
console.log(a * b);  // 30
console.log(a / b);  // 3.333...
console.log(a % b);  // 1
console.log(a ** b); // 1000

// 賦值運算子
let x = 5;
x += 3;  // x = x + 3
x -= 2;  // x = x - 2
x *= 4;  // x = x * 4
x /= 2;  // x = x / 2

// 比較運算子
console.log(a == b);   // false
console.log(a != b);   // true
console.log(a > b);    // true
console.log(a >= b);   // true

// 邏輯運算子
let isTrue = true;
let isFalse = false;
console.log(isTrue && isFalse);  // false
console.log(isTrue || isFalse);  // true
console.log(!isTrue);            // false
```

```swift !! swift
// Swift 運算子
let a = 10
let b = 3

// 算術運算子
print(a + b)  // 13
print(a - b)  // 7
print(a * b)  // 30
print(a / b)  // 3 (整數除法)
print(a % b)  // 1
print(pow(Double(a), Double(b))) // 1000.0

// 賦值運算子
var x = 5
x += 3  // x = x + 3
x -= 2  // x = x - 2
x *= 4  // x = x * 4
x /= 2  // x = x / 2

// 比較運算子
print(a == b)   // false
print(a != b)   // true
print(a > b)    // true
print(a >= b)   // true

// 邏輯運算子
let isTrue = true
let isFalse = false
print(isTrue && isFalse)  // false
print(isTrue || isFalse)  // true
print(!isTrue)            // false

// 範圍運算子
let range1 = 1...5    // 閉區間 (1, 2, 3, 4, 5)
let range2 = 1..<5    // 半開區間 (1, 2, 3, 4)
```
</UniversalEditor>

### 5.2 字串操作

Swift 提供強大的字串插值和操作功能。

<UniversalEditor title="字串操作" compare={true}>
```javascript !! js
// JavaScript 字串操作
let firstName = "John";
let lastName = "Doe";

// 字串連接
let fullName = firstName + " " + lastName;
console.log(fullName); // "John Doe"

// 模板字面量
let greeting = `Hello, ${firstName} ${lastName}!`;
console.log(greeting); // "Hello, John Doe!"

// 字串方法
let message = "Hello World";
console.log(message.length);           // 11
console.log(message.toUpperCase());    // "HELLO WORLD"
console.log(message.toLowerCase());    // "hello world"
console.log(message.indexOf("World")); // 6
console.log(message.substring(0, 5));  // "Hello"
console.log(message.replace("World", "Swift")); // "Hello Swift"

// 字串比較
let str1 = "apple";
let str2 = "Apple";
console.log(str1 === str2); // false
console.log(str1.toLowerCase() === str2.toLowerCase()); // true
```

```swift !! swift
// Swift 字串操作
let firstName = "John"
let lastName = "Doe"

// 字串連接
let fullName = firstName + " " + lastName
print(fullName) // "John Doe"

// 字串插值
let greeting = "Hello, \(firstName) \(lastName)!"
print(greeting) // "Hello, John Doe!"

// 字串方法
let message = "Hello World"
print(message.count)                    // 11
print(message.uppercased())             // "HELLO WORLD"
print(message.lowercased())             // "hello world"
print(message.contains("World"))        // true
print(message.prefix(5))                // "Hello"
print(message.replacingOccurrences(of: "World", with: "Swift")) // "Hello Swift"

// 字串比較
let str1 = "apple"
let str2 = "Apple"
print(str1 == str2) // false
print(str1.lowercased() == str2.lowercased()) // true

// 多行字串
let multiLine = """
    This is a
    multi-line
    string in Swift
    """
print(multiLine)
```
</UniversalEditor>

## 6. 註釋和文件

### 6.1 註釋樣式

兩種語言都支援類似的註釋樣式，但 Swift 有額外的文件功能。

<UniversalEditor title="註釋和文件" compare={true}>
```javascript !! js
// JavaScript 註釋和文件

// 單行註釋
let name = "John"; // 這是一個變數

/*
 * 多行註釋
 * 這是一個塊註釋
 * 可以跨越多行
 */

/**
 * JSDoc 函數文件註釋
 * @param {string} name - 要問候的名字
 * @param {number} age - 人的年齡
 * @returns {string} 問候訊息
 */
function greetPerson(name, age) {
    return `Hello ${name}, you are ${age} years old`;
}

// 內聯註釋
let result = 5 + 3; // 計算總和
```

```swift !! swift
// Swift 註釋和文件

// 單行註釋
let name = "John" // 這是一個變數

/*
 * 多行註釋
 * 這是一個塊註釋
 * 可以跨越多行
 */

/**
 * Swift 文件註釋
 * - Parameter name: 要問候的名字
 * - Parameter age: 人的年齡
 * - Returns: 問候訊息
 */
func greetPerson(name: String, age: Int) -> String {
    return "Hello \(name), you are \(age) years old"
}

// 內聯註釋
let result = 5 + 3 // 計算總和

// MARK: - 程式碼組織部分標記
// MARK: 屬性
let title = "My App"

// MARK: 方法
func doSomething() {
    // 實作
}

// TODO: - 未來工作提醒
// TODO: 實作錯誤處理

// FIXME: - 標記需要修復的 bug
// FIXME: 這個需要優化
```
</UniversalEditor>

## 7. 練習

### 練習 1: 變數和函數練習

<UniversalEditor title="練習 1: 基礎語法" compare={true}>
```javascript !! js
// JavaScript 練習
// 1. 宣告一個人的資訊變數
let personName = "Alice";
let personAge = 25;
let personCity = "New York";

// 2. 建立計算 BMI 的函數
function calculateBMI(weight, height) {
    return weight / (height * height);
}

// 3. 建立返回格式化字串的函數
function formatPersonInfo(name, age, city) {
    return `${name} is ${age} years old and lives in ${city}`;
}

// 4. 測試函數
let bmi = calculateBMI(70, 1.75);
console.log(`BMI: ${bmi.toFixed(2)}`);
console.log(formatPersonInfo(personName, personAge, personCity));
```

```swift !! swift
// Swift 練習
// 1. 宣告一個人的資訊變數
let personName: String = "Alice"
let personAge: Int = 25
let personCity: String = "New York"

// 2. 建立計算 BMI 的函數
func calculateBMI(weight: Double, height: Double) -> Double {
    return weight / (height * height)
}

// 3. 建立返回格式化字串的函數
func formatPersonInfo(name: String, age: Int, city: String) -> String {
    return "\(name) is \(age) years old and lives in \(city)"
}

// 4. 測試函數
let bmi = calculateBMI(weight: 70, height: 1.75)
print("BMI: \(String(format: "%.2f", bmi))")
print(formatPersonInfo(name: personName, age: personAge, city: personCity))
```
</UniversalEditor>

### 練習 2: 控制流練習

<UniversalEditor title="練習 2: 控制流" compare={true}>
```javascript !! js
// JavaScript 控制流練習
function gradeCalculator(score) {
    if (score >= 90) {
        return "A";
    } else if (score >= 80) {
        return "B";
    } else if (score >= 70) {
        return "C";
    } else if (score >= 60) {
        return "D";
    } else {
        return "F";
    }
}

function numberAnalyzer(number) {
    let result = "";
    
    if (number > 0) {
        result += "正數 ";
    } else if (number < 0) {
        result += "負數 ";
    } else {
        result += "零 ";
    }
    
    if (number % 2 === 0) {
        result += "偶數";
    } else {
        result += "奇數";
    }
    
    return result;
}

// 測試函數
console.log(gradeCalculator(85)); // "B"
console.log(numberAnalyzer(7));   // "正數 奇數"
console.log(numberAnalyzer(-4));  // "負數 偶數"
```

```swift !! swift
// Swift 控制流練習
func gradeCalculator(score: Int) -> String {
    switch score {
    case 90...100:
        return "A"
    case 80..<90:
        return "B"
    case 70..<80:
        return "C"
    case 60..<70:
        return "D"
    case 0..<60:
        return "F"
    default:
        return "無效分數"
    }
}

func numberAnalyzer(number: Int) -> String {
    var result = ""
    
    if number > 0 {
        result += "正數 "
    } else if number < 0 {
        result += "負數 "
    } else {
        result += "零 "
    }
    
    if number % 2 == 0 {
        result += "偶數"
    } else {
        result += "奇數"
    }
    
    return result
}

// 測試函數
print(gradeCalculator(score: 85)) // "B"
print(numberAnalyzer(number: 7))   // "正數 奇數"
print(numberAnalyzer(number: -4))  // "負數 偶數"
```
</UniversalEditor>

## 8. 關鍵要點

### 8.1 語法差異總結

| 特性 | JavaScript | Swift | 關鍵差異 |
|---|---|---|---|
| **變數宣告** | `let/const/var` | `let/var` | Swift 使用 `let` 表示常數，沒有 `const` |
| **類型系統** | 動態類型 | 靜態類型 | Swift 需要顯式類型或類型推斷 |
| **函數參數** | 無標籤 | 外部參數名 | Swift 使用參數標籤提高清晰度 |
| **字串插值** | `${variable}` | `\(variable)` | 字串插值的不同語法 |
| **Switch 語句** | 基本匹配 | 模式匹配 | Swift 支援複雜的模式匹配 |
| **迴圈語法** | `for...of`, `for...in` | `for...in` | Swift 的 `for...in` 更通用 |
| **類型檢查** | 執行時 | 編譯時 | Swift 在執行前捕獲錯誤 |

### 8.2 最佳實踐

1. **使用類型註解**: 顯式宣告類型提高程式碼清晰度
2. **優先使用常數**: 盡可能使用 `let` 而不是 `var`
3. **使用參數標籤**: 使函數呼叫更易讀
4. **利用模式匹配**: 使用 Swift 強大的 switch 語句
5. **編寫清晰文件**: 使用 Swift 的文件註釋
6. **遵循命名約定**: 變數和函數使用 camelCase
7. **使用字串插值**: 優先使用 `\(variable)` 而不是連接

### 8.3 常見陷阱

1. **忘記類型註解**: Swift 的類型推斷很好，但顯式類型有幫助
2. **混用 `let` 和 `var`**: 常數使用 `let`，只在需要時使用 `var`
3. **忽略參數標籤**: 它們使程式碼更易讀
4. **不使用模式匹配**: Swift 的 switch 語句很強大
5. **String vs Character**: Swift 區分 String 和 Character 類型

## 9. 下一步

在下一個模組中，我們將詳細探索 Swift 的類型系統，包括：
- 可選類型和 nil 安全性
- 類型推斷和類型註解
- 類型別名和類型轉換
- 類型安全程式設計實踐

這個 Swift 語法基礎將為你準備即將到來的模組中的更高級概念。 